<?php
/**
 * Created by PhpStorm.
 * User: jaylen
 * Date: 2020-05-29
 * Time: 21:05
 */

namespace app\common\model;


use app\common\exception\ParameterException;
use app\common\model\traits\CaseContent;
use app\common\model\traits\ContentBaseTraits;
use app\common\model\traits\InformationContent;
use think\facade\Db;
use think\model\concern\SoftDelete;
use app\common\validate\Content as Validate;
use app\admin\model\ModelTable as ModelTableModel;

class Content extends BaseModel
{
    protected $hidden = ['update_time','delete_time'];

    // 使用软删除
    use SoftDelete;
    protected $deleteTime = 'delete_time';

    protected const case_category_id = 1;
    protected const information_category_id = 2;

    use ContentBaseTraits;
    use CaseContent;
    use InformationContent;

    public function category()
    {
        return $this->belongsTo('Category','category_id','id')
            ->field(['id','title']);
    }

    public function modelTable()
    {
        return $this->belongsTo('\\app\\admin\\model\\ModelTable','model_id','id');
    }

    public function contentViewUser()
    {
        return $this->hasMany('ContentViewUser','content_id','id');
    }

    public function contentLikeUser()
    {
        return $this->hasMany('ContentLikeUser','content_id','id');
    }

    public function contentShareUser()
    {
        return $this->hasMany('ContentShareUser','content_id','id');
    }

    public function getMainImageAttr($value,$data)
    {
        return [
            'value' => $value,
            'prefix' => $this->prefixImgUrl($value)
        ];
    }

    /**
     * 获取内容的分页数据
     * @param array $params
     * @return \think\Paginator
     */
    public static function getPaginationList(array $params)
    {
        static::validatePaginationData($params);

        $static = new static();

        $static = $static->with(['category', 'modelTable' => function($query) {
            $query->field(['id','cn_name']);
        }]);

        foreach ($params as $name => $value) {
            $value = trim($value);
            switch ($name) {
                case 'title':
                    if (!empty($value)) {
                        $like_text = '%' . $value . '%';
                        $static = $static->whereLike('title', $like_text);
                    }
                    break;
                case 'category_id':
                    if (!empty($value)) {
                        $static = $static->where('category_id','=',intval($value));
                    }
                    break;
                case 'model_id':
                    if (!empty($value)) {
                        $static = $static->where('model_id','=',intval($value));
                    }
                    break;
                case 'sort_order':
                    if (!empty($value)) {
                        $static = $static->order($params['sort_prop'], $value == 'descending' ? 'desc' : 'asc');
                    }
                    break;
            }
        }

        return $static
            ->paginate([
                'page' => $params['page'],
                'list_rows' => $params['limit']
            ], false);
    }

    /**
     * 获取对应操作类型的用户分页数据
     * @param $params
     * @return \think\Paginator
     */
    public static function getOperationUserPaginationList(array $params)
    {
        static::validatePaginationData($params);

        $static = static::find($params['id']);

        switch ($params['type']) {
            case 'view' :
                $static = $static->contentViewUser()->with('user');
                break;
            case 'like' :
                $static = $static->contentLikeUser()->with('user');
                break;
            case 'share' :
                $static = $static->contentShareUser()->with('user');
                break;
        }

        return $static->paginate([
            'page' => $params['page'],
            'list_rows' => $params['limit'],
        ],false);
    }

    /**
     * 获取对应栏目的内容分页数据
     * @param array $params
     * @return array
     */
    public static function getMpPaginationList(array $params)
    {

        static::validatePaginationData($params);

        $validate = new Validate();
        if (!$validate->scene('paginate')->check($params)) {
            throw new ParameterException([
                'msg' => $validate->getError(),
            ]);
        }

        switch($params['type']) {
            case 'case' :
                return static::getCaseCategoryPaginate($params);
                break;
            case 'information' :
                return static::getInformationCategoryPaginate($params);
                break;
        }
    }

    /**
     * 获取推荐的内容
     * @param array $params
     * @return mixed
     */
    public static function getRecommData(array $params)
    {
        $validate = new Validate();
        if (!$validate->scene('recomm')->check($params)) {
            throw new ParameterException([
                'msg' => $validate->getError(),
            ]);
        }

        switch($params['type']) {
            case 'case' :
                return static::getCaseRecommData($params['limit']);
                break;
            case 'information' :
                return static::getInformationRecommData($params['limit']);
                break;
        }
    }

    /**
     * 获取指定书目最新的内容数据
     * @param array $params
     * @return mixed
     */
    public static function getNewestData(array $params)
    {
        $validate = new Validate();
        if (!$validate->scene('newest')->check($params)) {
            throw new ParameterException([
                'msg' => $validate->getError(),
            ]);
        }

        switch($params['type']) {
            case 'case' :
                return static::getCaseNewestData($params['limit']);
                break;
            case 'information' :
                return static::getInformationNewestData($params['limit']);
                break;
        }
    }

    /**
     * 根据内容id获取内容的详细数据(显示在微信小程序上)
     * @param $params
     * @return array|\think\Model|null
     */
    public static function getMpShowContentByID($params)
    {
        $validate = new Validate();
        if (!$validate->scene('data')->check($params)) {
            throw new ParameterException([
                'msg' => $validate->getError(),
            ]);
        }

        switch($params['type']) {
            case 'case' :
                return static::getCaseContentData($params['id']);
                break;
            case 'information' :
                return static::getInformationContentData($params['id']);
                break;
        }
    }

    /**
     * 添加内容数据
     * @param array $data
     * @return bool
     */
    public static function addContent(array $data)
    {
        $validate = new Validate();
        if (!$validate->scene('add')->check($data)) {
            throw new ParameterException([
                'msg' => $validate->getError(),
            ]);
        }

        $model_name = ModelTableModel::getTableEnNameByID($data['model_id']);
        $static = new static();

        static::handleSubmitData($data);

        if (empty($data['table_data']) || empty($model_name)) {
            return false;
        }

        $static->startTrans();

        try {

            $table_id = Db::name($model_name)->insertGetId($data['table_data']);

            $data['table_id'] = $table_id;

            $static->allowField(['title','main_image','category_id','model_id','table_id','view_count','like_count','share_count','sort','recomm','status'])
                ->save($data);

            $static->commit();

        }catch (\Exception $e) {
            $static->rollback();
            return false;
        }

        return true;
    }

    /**
     * 编辑内容信息
     * @param array $data
     * @return bool
     */
    public static function editContent(array $data)
    {
        $validate = new Validate();
        if (!$validate->scene('edit')->check($data)) {
            throw new ParameterException([
                'msg' => $validate->getError(),
            ]);
        }

        $model_name = ModelTableModel::getTableEnNameByID($data['model_id']);
        $static = static::find($data['id']);

        static::handleSubmitData($data);

        if (empty($data['table_data']) || empty($model_name)) {
            return false;
        }

        $needDeleteFile = [];

        $static->startTrans();

        try {
            // 判断是否切换了模型
            if ($static->model_id != $data['model_id']) {
                $old_model_name = ModelTableModel::getTableEnNameByID($static->model_id);
                $old_data = Db::name($old_model_name)
                    ->where('id','=',$static->table_id)
                    ->find();
                $old_fields_data = ModelTableModel::getFieldsData([
                    'id' => $static->model_id,
                    'table_id' => $static->table_id
                ]);

                $needDeleteFile = static::getNeedDeleteFile($old_fields_data, $old_data, true);

                // 先删除旧模型中的内容，再往新模型表中添加对于的内容
                Db::name($old_model_name)
                    ->where('id','=',$static->table_id)
                    ->delete();

                $table_id = Db::name($model_name)->insertGetId($data['table_data']);
                $data['table_id'] = $table_id;
            } else {
                $old_data = Db::name($model_name)
                    ->where('id','=',$static->table_id)
                    ->find();
                $needDeleteFile = static::getNeedDeleteFile($data['fields_data'],$old_data);

                Db::name($model_name)
                    ->where('id','=',$static->table_id)
                    ->update($data['table_data']);
            }

            $static->allowField(['id','title','main_image','category_id','model_id','table_id','view_count','like_count','share_count','sort','recomm','status'])
                ->save($data);

            $static->commit();
        }catch (\Exception $e) {
            $static->rollback();
            return false;
        }

        if (!empty($needDeleteFile)) {
            delFile($needDeleteFile);
        }

        return true;
    }

    /**
     * 检查对应操作的用户是否已经操作
     * @param $params
     * @return bool
     */
    public static function checkOperationUser($params)
    {
        $validate = new Validate();
        if (!$validate->scene('operation')->check($params)) {
            throw new ParameterException([
                'msg' => $validate->getError(),
            ]);
        }

        switch ($params['type']) {
            case 'like' :
                return static::checkLikeUser($params['id']);
                break;
            case 'view' :
                return static::checkViewUser($params['id']);
                break;
            case 'share' :
                return static::checkShareUser($params['id']);
                break;
        }
    }

    /**
     * 更新操作的用户数据
     * @param $params
     * @return mixed
     */
    public static function updateOperationUser($params)
    {
        $validate = new Validate();
        if (!$validate->scene('operation')->check($params)) {
            throw new ParameterException([
                'msg' => $validate->getError(),
            ]);
        }

        if ($params['only_check'] == true) {
            return true;
        }

        switch ($params['type']) {
            case 'like' :
                if (isset($params['get_user_list']) && $params['get_user_list']) {
                    static::updateLikeUser($params['id']);
                    return static::getLikeUserAfterUpdate($params['id']);
                } else {
                    return static::updateLikeUser($params['id']);
                }
                break;
            case 'view' :
                return static::updateViewUser($params['id'], $params['add_user']);
                break;
            case 'share' :
                return static::updateShareUser($params['id'], $params['add_user']);
                break;
        }
    }
}